package com.study.streamApi;

/**
 * StreamAPI大全案例
 *
 * @author yangyanbin
 * @since 20221103
 **/

import com.study.collectors.Bean.User;
import org.springframework.beans.BeanUtils;

import java.math.BigDecimal;
import java.text.DecimalFormat;
import java.util.*;
import java.util.function.Function;
import java.util.stream.Collectors;

public class StreamApiAll {
    public static void main(String[] args) {

        // key->age 包含唯一的key
        List<User> userList = Arrays.asList(
                new User(1, "张三", 13, "帅气"),
                new User(2, "李四", 14, "哈哈"),
                new User(3, "王五", 17, "开口"),
                new User(4, "赵六", 16, "偶看")
        );
        // key->age 包含重复的key
        List<User> userList2 = Arrays.asList(
                new User(1, "张三", 13, "帅气"),
                new User(3, "王五", 10, "开口"),
                new User(2, "李四", 19, "哈哈"),
                new User(4, "赵六", 19, "偶看"),
                new User(4, "李琪", 10, "偶看")
        );
        //按年龄正序
        List<User> collect = userList.stream()
                .sorted(Comparator.comparing(User::getAge))
                .collect(Collectors.toList());
        System.out.println("collect:   " + collect);

        //去重
        List<User> collect1 = userList2.stream().distinct().collect(Collectors.toList());
        System.out.println("collect1:   " + collect1);

        //按年龄逆序
        List<User> collect2 = userList.stream()
                .sorted(Comparator.comparing(User::getAge)
                        .reversed())
                .collect(Collectors.toList());
        System.out.println("collect2:   " + collect2);

        //先按年龄逆序，再按地址逆序
        List<User> collect3 = userList2.stream()
                .sorted(Comparator.comparing(User::getAge)
                        .thenComparing(User::getAdress).reversed())
                .collect(Collectors.toList());
        System.out.println("collect3:   " + collect3);

        //抽取名字为" 张三-abc "形式的集合
        List<String> collect4 = userList.stream().map(e -> {
            return e.getName() + "-" + e.getAdress();
        }).collect(Collectors.toList());
        System.out.println("collect4:   " + collect4);

        //将集合中的名字改为" address-name "的形式
        List<User> collect5 = userList.stream().map(e -> {
            User user = new User();
            user.setName(e.getAdress() + "-" + e.getName());
            user.setAge(e.getAge());
            user.setAdress(e.getAdress());
            user.setRemark(e.getRemark());
            return user;
        }).collect(Collectors.toList());
        System.out.println("collect5:   " + collect5);

        //将集合中的名字改为" address-name-remark "的形式
        List<User> collect6 = userList.stream().map(e -> {
            User user = new User();
            BeanUtils.copyProperties(e, user);
            user.setName(e.getAdress() + "-" + e.getName() + "-" + e.getRemark());
            return user;
        }).collect(Collectors.toList());
        System.out.println("collect6:   " + collect6);

        //是否所有的年龄都大于0
        boolean allMatch = userList.stream().allMatch(user -> user.getAge() > 1);
        System.out.println("allMatch:   " + allMatch);

        //是否有一个的年龄大于0
        boolean anyMatch = userList.stream().anyMatch(user -> user.getAge() > 3);
        System.out.println("anyMatch:   " + anyMatch);

        //是否所有的对象都不符合这个条件
        boolean noneMatch = userList.stream().noneMatch(user -> user.getAge() > 5);
        System.out.println("noneMatch:   " + noneMatch);

        //对年龄进行逆序
//        userList.sort(Comparator.comparing(User::getAge).reversed());

        //获取年龄最大的对象
        User user = userList.stream().max(Comparator.comparing(User::getAge)).get();
        System.out.println("user:   " + user);

        //获取年龄最大的对象并将他的name改为" nameaaa "的形式
        User user2 = userList.stream().max(Comparator.comparing(User::getAge)).map(e -> {
                    User user1 = new User();
                    BeanUtils.copyProperties(e, user1);
                    user1.setName(e.getName() + "aaa");
                    return user1;
                }
        ).get();
        System.out.println("user2:   " + user2);

        //截取前两个对象
        List<User> collect7 = userList.stream().limit(2).collect(Collectors.toList());
        System.out.println("collect7:   " + collect7);

        //抽取age为键，name为值，组成一个新的map()
        Map<Integer, String> map8 = userList.stream().collect(Collectors.toMap(User::getAge, User::getName));
        System.out.println("map8:   " + map8);

        //抽取age为键，name+aaa为值，组成一个新的map
        Map<Integer, String> map9 = userList.stream().collect(Collectors.toMap(User::getAge, user1 -> {
            return user1.getName() + "aaa";
        }));
        System.out.println("map9:   " + map9);

        //以age为键，对象为值，组成一个新的map
        Map<Integer, User> map10 = userList.stream().collect(Collectors.toMap(User::getAge, Function.identity()));
//        Map<Integer, User> map10 = userList.stream().collect(Collectors.toMap(User::getAge, u->u));
        System.out.println("map10:   " + map10);

        //以age为键，name为值，组成一个新的map，当key相同时，同时保留两个值，值为原始值+当前值(重点)
        Map<Integer, String> map11 = userList2.stream()
                .collect(Collectors.toMap(User::getAge, User::getName, (oldVal, currVal) -> oldVal + currVal));
        System.out.println("map11:   " + map11);

        //以age为键，name为值，组成一个新的map，当key相同时，保留当前值
        Map<Integer, String> map12 = userList2.stream()
                .collect(Collectors.toMap(User::getAge, User::getName, (oldVal, currVal) -> currVal));
        System.out.println("map12:   " + map12);
        map12.forEach((k, v) -> {
            System.out.println(k + "=====" + v);
        });

        //以age为键，name为值，组成一个新的map，当key相同时，保留当前值,并且按照key进行排序(sorted()、LinkedHashMap::new)
        Map<Integer, String> map13 = userList2.stream().sorted(Comparator.comparing(User::getAge))
                .collect(Collectors.toMap(User::getAge, User::getName, (oldVal, currVal) -> oldVal + currVal, LinkedHashMap::new));
        System.out.println("map13:   " + map13);


        //提取所有的name，并且拼接成一个字符串，用-连接
        String collect8 = userList.stream()
                .map(User::getName)
                .collect(Collectors.joining("-"));
        System.out.println("collect8:   " + collect8);

        //按照name是否等于张三进行分区，key为Boolean，value为对象集合
        Map<Boolean, List<User>> map14 = userList.stream()
                .collect(Collectors.partitioningBy(u -> u.getName().equals("张三")));
        System.out.println("map14:   " + map14);

        // Adress为key，age为值，组成一个新的map，当key相同时(age累加)
        Map<String, Integer> map15 = userList2.stream().collect(Collectors.toMap(User::getAdress, User::getAge,
                Integer::sum));
        System.out.println("map15:   " + map15);

        //过滤掉list中已经存在于list1中的元素
        List<String> list = userList.stream().map(User::getName).collect(Collectors.toList());
        List<String> list1 = Arrays.asList("张三", "张三", "李四");
        List<String> collect9 = list.stream().filter(e -> !list1.contains(e)).collect(Collectors.toList());
        System.out.println("collect9:   " + collect9);


        //过滤掉userList中name已经存在于list1中的对象
        List<String> list2 = Arrays.asList("张三", "张三", "李四");
        List<User> collect10 = userList.stream().filter(e -> !list2.contains(e.getName())).collect(Collectors.toList());
        System.out.println("collect10:   " + collect10);


        //以 name + adress 为分组
        Map<String, List<User>> map16 = userList.stream().collect(Collectors.groupingBy(e -> e.getName() + e.getAdress()));
        System.out.println("map16:   " + map16);

        //以adress分组，key为adress，value为每组中的个数
        Map<String, Long> map17 = userList.stream().collect(Collectors.groupingBy(User::getAdress, Collectors.counting()));
        System.out.println("map17:   " + map17);

        //以adress分组，并计算每组中的age的和
        Map<String, Integer> map18 = userList.stream().collect(Collectors.groupingBy(User::getAdress,
                Collectors.summingInt(User::getAge)));
        System.out.println("map18:   " + map18);

        //根据整个user对象分组，并计数
        Map<User, Long> map19 = userList.stream().collect(Collectors.groupingBy(Function.identity(), Collectors.counting()));
        System.out.println("map19:   " + map19);


        // 按条件删除list中的元素 Arrays.asList(arr)方法返回的list，不支持add,move操作
        boolean removeIf = userList.removeIf(x -> x.equals(1));
        System.out.println("removeIf = " + removeIf);


        //求百分数
        DecimalFormat df = new DecimalFormat("0.0%");
        //可以设置精确几位小数
//        df.setMaximumFractionDigits(0);
        //模式 例如四舍五入
//        df.setRoundingMode(RoundingMode.HALF_UP);
        BigDecimal num = new BigDecimal(330.000);
        BigDecimal total = new BigDecimal(1000.777);
        BigDecimal divide = num.divide(total, 3, BigDecimal.ROUND_HALF_UP);
        System.out.println(df.format(divide));
    }
}


